﻿#ifndef CONFIG_H
#define CONFIG_H

#include <QString>
#include <QMap>
#include <QList>
#include <QColor>
#include <QJsonObject>
#include <QIcon>

#include "controlinfo.h"

// Router Configuration
class ConfigRouterItem
{
public:
    QString         ip;
    int             port;
    QList<int>      addrs;

public:
    const static QString keyIp;
    const static QString keyPort;
    const static QString keyAddrs;
};

class ConfigRouter
{
public:
    typedef QList<ConfigRouterItem> RouterList;

public:
    RouterList routers;

public:
    const static QString key;
};

// Gyscada configuration
class ConfigGyscada
{
public:
    QString         ip;
    int             port;
    int             t0;
    int             t1;
    int             t2;
    int             timer;

public:
    const static QString keyIp;
    const static QString keyPort;
    const static QString keyT0;
    const static QString keyT1;
    const static QString keyT2;
    const static QString keyTimer;
    const static QString keyGyscada;
};

// MySQL configuration
class ConfigMySQL
{
public:
    QString         ip;
    int             port;
    QString         db;
    QString         user;
    QString         password;
    QString         user_table;
    QString         log_table;
    QString         staffer_table;

public:
    const static QString keyIp;
    const static QString keyPort;
    const static QString keyDB;
    const static QString keyUser;
    const static QString keyPassword;
    const static QString keyUserTable;
    const static QString keyStafferTable;
    const static QString keyLogTable;
    const static QString key;
};

// Transition Configuration
class ConfigTransitionItem
{
public:
    int             id;
    int             defaultstate;
    QMap<int, int>  templates;

public:
    const static QString keyId;
    const static QString keyDefaultState;
    const static QString keyTemplates;
    const static QString keyTemplatesPoint;
    const static QString keyTemplatesState;
};

class ConfigTransition
{
public:
    typedef QMap<int, ConfigTransitionItem> TransitionMap;

public:
    TransitionMap transitions;

public:
    const static QString key;
};

// Point Configuration
class ConfigPointItem
{
public:
    int             id;
    QString         title;
    QString         unit;

public:
    const static QString keyId;
    const static QString keyTitle;
    const static QString keyUnit;
};

class ConfigPoint
{
public:
    typedef QMap<int, ConfigPointItem> PointMap;

public:
    PointMap points;

public:
    const static QString key;
};

// Station Configuration
class ConfigStationItem
{
public:
    typedef QMap<int, ControlInfo> StationControlMap;

public:
    int                 id;
    QString             name;
    QList<int>          lines;
    StationControlMap   controls;

public:
    const static QString keyId;
    const static QString keyName;
    const static QString keyLines;
    const static QString keyControls;
};

class ConfigStation
{
public:
    typedef QMap<int, ConfigStationItem> StationMap;

public:
    StationMap stations;

public:
    const static QString key;
};

// Line Configuration
class ConfigLineItem
{
public:
    typedef QMap<int, ControlInfo> LineControlMap;

public:
    int             id;
    QString         name;
    QList<int>      turbines;
    LineControlMap  controls;

public:
    const static QString keyId;
    const static QString keyName;
    const static QString keyTurbines;
    const static QString keyControls;
};

class ConfigLine
{
public:
    typedef QMap<int, ConfigLineItem> LineMap;

public:
    LineMap lines;

public:
    const static QString key;
};

// Turbine Configuration
class ConfigTurbineItem
{
public:
    typedef QMap<int, QString> TurbinePointMap;
    typedef QMap<int, ControlInfo> TurbineControlMap;

public:
    int                 id;
    int                 statepoint;
    int                 statetransition;
    QString             name;
    TurbinePointMap     points;
    TurbineControlMap   controls;

public:
    const static QString keyId;
    const static QString keyName;
    const static QString keyControls;
    const static QString keyStatePoint;
    const static QString keyStateTransition;
    const static QString keyPoints;
    const static QString keyPointsId;
    const static QString keyPointsAddr;
};

class ConfigTurbine
{
public:
    typedef QMap<int, ConfigTurbineItem> TurbineMap;

public:
    TurbineMap turbines;

public:
    const static QString key;
};

// Control Configuration
class ConfigControlItem
{
public:
    int     id;
    QString title;
    QString description;
    QString shortcut;
    QString icon;
    QString dlgtitle;
    int     type;
    double  defaultvalue;
    double  minvalue;
    double  maxvalue;
    int     decimals;

public:
    const static QString keyId;
    const static QString keyTitle;
    const static QString keyDescription;
    const static QString keyShortCut;
    const static QString keyIcon;
    const static QString keyType;
    const static QString keyDlgTitle;
    const static QString keyDefaultValue;
    const static QString keyMinValue;
    const static QString keyMaxValue;
    const static QString keyDecimals;
};

class ConfigControl
{
public:
    typedef QMap<int, ConfigControlItem> ControlMap;

public:
    ControlMap controls;

public:
    const static QString key;
};

// State Configuration
class ConfigStateItem
{
public:
    int     id;
    QString title;
    QString description;
    QColor  color;
    QIcon   icon;

public:
    const static QString keyId;
    const static QString keyTitle;
    const static QString keyDescription;
    const static QString keyColor;
    const static QString keyIcon;
};

class ConfigState
{
public:
    typedef QMap<int, ConfigStateItem> StateMap;

public:
    StateMap states;

public:
    const static QString key;
};

// Configuration
class GYSCADAConfig
{
public:
    static GYSCADAConfig* getInstance();

protected:
    GYSCADAConfig();

private:
    static GYSCADAConfig* instance;

public:
    bool parse();

    // Get Transition config item
    QMap<int, int> getTransitionTemplate(int id);
    int getTransitionDefaultState(int id);

    // Get State config item
    QString getStateTitle(int id);
    QColor getStateColor(int id);
    QIcon getStateIcon(int id);

    // Get Control config item
    QList<int> getControlIds();
    int getControlType(int id);
    QIcon getControlIcon(int id);
    QString getControlTitle(int id);
    QString getControlShortCut(int id);
    QString getControlDescription(int id);
    QString getControlDlgTitle(int id);
    double getControlDefaultValue(int id);
    double getControlMaxValue(int id);
    double getControlMinValue(int id);
    int getControlDecimals(int id);

    // Get Station config item;
    QList<int> getStationIds();
    QString getStationName(int id);
    QList<int> getStationLines(int id);
    QMap<int, ControlInfo> getStationControls(int id);

    // Get Line config items;
    QList<int> getLineIds();
    QString getLineName(int id);
    QList<int> getLineTurbines(int id);
    QMap<int, ControlInfo> getLineControls(int id);

    // Get Turbine config items;
    QList<int> getTurbineIds();
    QString getTurbineName(int id);
    QMap<int, ControlInfo> getTurbineControls(int id);
    QMap<int, QString> getTurbinePoints(int id);
    QMap<int, int> getTurbineTransition(int id);
    int getTurbineDefaultState(int id);
    int getTurbineStatePoint(int id);

    // Get Point config items;
    QList<int> getPointIds();
    QString getPointTitle(int id);
    QString getPointUnit(int id);

    // Get Gyscada item
    QString getGyscadaIp();
    int getGyscadaPort();
    int getGyscadaT0();
    int getGyscadaT1();
    int getGyscadaT2();
    int getGyscadaTimer();

    // Get MySQL
    QString getMySQLIp();
    int getMySQLPort();
    QString getMySQLDB();
    QString getMySQLUser();
    QString getMySQLPassword();
    QString getMySQLUserTable();
    QString getMySQLStafferTable();
    QString getMySQLLogTable();

    // Get Router
    QList<ConfigRouterItem>& getRouterList();

protected:
    bool parseGyscada(QJsonObject& objRoot);
    bool parseMySQL(QJsonObject& objRoot);
    bool parseControl(QJsonObject& objRoot);
    bool parseState(QJsonObject& objRoot);
    bool parseTurbine(QJsonObject& objRoot);
    bool parseLine(QJsonObject& objRoot);
    bool parseStation(QJsonObject& objRoot);
    bool parsePoint(QJsonObject& objRoot);
    bool parseTransition(QJsonObject& objRoot);
    bool parseRouter(QJsonObject& objRoot);
    void fillControlInfo();

protected:
    ConfigControl           control;
    ConfigState             state;
    ConfigTurbine           turbine;
    ConfigLine              line;
    ConfigStation           station;
    ConfigPoint             point;
    ConfigTransition        transition;
    ConfigGyscada           gyscada;
    ConfigRouter            router;
    ConfigMySQL             mysql;

private:
    const static QString    fileName;

public:
    void setStafferName(const QString& stafferName)
    {
        this->stafferName = stafferName;
    }
    void setUserName(const QString& userName)
    {
        this->userName = userName;
    }
    void setUserId(int userId)
    {
        this->userId = userId;
    }
    const QString& getStafferName()
    {
        return this->stafferName;
    }
    const QString& getUserName()
    {
        return this->userName;
    }
    int getUserId()
    {
        return this->userId;
    }
private:
    QString     stafferName;
    QString     userName;
    int         userId;
};

#endif // CONFIG_H
